package cn.jekun.shop.web.service;


import java.sql.Types;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.jekun.component.base.exceptions.BusinessException;
import cn.jekun.component.base.utils.SqlUtis;
import cn.jekun.component.base.validator.annotation.Mobile;
import cn.jekun.component.core.Constants;
import cn.jekun.component.core.bean.gen.ErpOrders;
import cn.jekun.component.core.bean.gen.ErpTxnSeq;
import cn.jekun.component.core.service.ConfigService;
import cn.jekun.component.core.service.gen.ErpOrdersService;
import cn.jekun.component.core.service.gen.ErpTxnSeqService;
import cn.jekun.component.pay.common.service.CommonMethodService;
import cn.jekun.component.pay.common.utils.ChinaUnionPayConfig;
import cn.jekun.component.pay.unionpay.tools.QuickPayUtils;
import cn.jekun.component.shop.service.OrderService;
import cn.jekun.component.shop.service.ThirdBusinessService;
import cn.jekun.shop.common.service.ShopBaseService;
/**
 * 第三方支付
 * @author twj
 *
 */
@Service(TransactionService.BEAN_NAME)
public class TransactionService extends ShopBaseService{
public static final String BEAN_NAME = "cn.jekun.shop.web.service.TransactionService";

	@Resource(name=ErpOrdersService.BEAN_NAME)
	ErpOrdersService orpOrdersService;	
	
	@Resource(name=ChinaUnionPayService.BEAN_NAME)
	ChinaUnionPayService chinaUnionPayService;
	
	@Resource(name=AlipayWebService.BEAN_NAME)
	AlipayWebService alipayWebService;
	
	@Resource(name=AlipayWapService.BEAN_NAME)
	AlipayWapService alipayWapService;
	
	@Resource(name=OrderService.BEAN_NAME)
	OrderService orderService;
	
	@Resource(name=CommonMethodService.BEAN_NAME)
	CommonMethodService commonMethodService;
	
	@Resource(name=cn.jekun.shop.common.service.OrderService.BEAN_NAME)
	cn.jekun.shop.common.service.OrderService OrderService1;
	
	@Resource(name=ErpTxnSeqService.BEAN_NAME)
	ErpTxnSeqService erpTxnSeqService;
	
	@Resource(name=ThirdBusinessService.BEAN_NAME)
	ThirdBusinessService thirdBusinessService;
	
	/**
	 * 支付中转站（重组第三方支付所需参数）
	 * @param order
	 * @param clientIp
	 * @param userId
	 * @param mobile
	 * @param payType
	 * @param totalMoney
	 * @return
	 */
	 
	public JSONObject reconstructParams(@ErpOrders.AnnoOrderId String order,
			String clientIp,
			@ErpOrders.AnnoUserId String userId,
			@Mobile(message="手机格式不正确") String mobile,
			String payType,
			@ErpOrders.AnnoTotalAmount String totalMoney){
		JSONObject jsonObject = new JSONObject();
		if (StringUtils.isBlank(order)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"订单号不能为空");
		}
		if (order.startsWith("FK")) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"暂时不允许合并支付");
		}
		if (StringUtils.isBlank(clientIp)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"客户端IP不能为空");
		}
		if (StringUtils.isBlank(userId)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"用户编码不能为空");
		}
		if (StringUtils.isBlank(mobile)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"手机号不能为空");
		}
		if (StringUtils.isBlank(payType)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"支付方式不能为空");
		}
		if(Constants.ONLINE_PAYMENT.CHINA_UNION_PAY.equals(payType)){
			jsonObject = chinaUnionPayService.genUnionPayParams(order,clientIp,userId,mobile);
		}
		if(Constants.ONLINE_PAYMENT.ALIPAY_WEB.equals(payType)){
			jsonObject = alipayWebService.genAlipayParams(order, clientIp, userId, mobile);
		}
		if(Constants.ONLINE_PAYMENT.ALIPAY_WAP.equals(payType)){
			jsonObject = alipayWapService.genAlipayParams(order, clientIp, userId, mobile);
		}
		if(jsonObject.get("code").toString().equals("1")){
			return executeRerutn(jsonObject);
		}
		else{
			return executeRerutnFail(jsonObject);
		}
	}
	
	/**
	 *  后台通知支付结果处理
	 * @param resArr
	 * @param signature
	 * @param signMethod
	 * @param orderId     订单号
	 * @param userId      用户编码
	 * @param transType   交易类型
	 * @return
	 */
	 

	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Transactional
	public JSONObject backNotify(String[] resArr, String signature, String signMethod,String orderId,String userId,String transType){
		JSONObject jsonObject = new JSONObject();
		if (StringUtils.isBlank(userId)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"用户编码不能为空");
		}
		if (StringUtils.isBlank(orderId)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"订单号不能为空");
		}
		if (StringUtils.isBlank(signature)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"签名信息不能为空");
		}
		if (StringUtils.isBlank(signMethod)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"签名方法不能为空");
		}
		if (StringUtils.isBlank(transType)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"交易类型不能为空");
		}
		Boolean signatureCheck = new QuickPayUtils().checkSign(resArr, signMethod, signature,ConfigService.getConfig(ChinaUnionPayConfig.KEY_UNIONPAY_SENDCERTKEY_PWD));
		
		if(!signatureCheck){
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"支付签名验证有误");
		}
		//交易类型是消费
		System.out.println("==================交易类型："+transType);
		if("01".equals(transType)){
			String orderAmount = resArr[6];
			//2:判断ErpTxnSeq中是否存在返回的请求支付订单号并且交易状态0的记录
			Map formMap = new HashMap();
			formMap.put(ErpTxnSeq.COL_ORDER_ID, orderId);
			formMap.put(ErpTxnSeq.COL_TXN_STATE, "0");
			formMap.put(ErpTxnSeq.COL_DEL_FLAG, "0");
			SqlUtis.prepareSql(formMap,
					SqlUtis.getSQL(formMap, "a."
							+ ErpTxnSeq.COL_ORDER_ID,Types.VARCHAR,SqlUtis.EQ),
							SqlUtis.getSQL(formMap, "a."
									+ ErpTxnSeq.COL_TXN_STATE,Types.VARCHAR,SqlUtis.EQ),
									SqlUtis.getSQL(formMap, "a."
											+ ErpTxnSeq.COL_DEL_FLAG,Types.VARCHAR,SqlUtis.EQ));
			ErpTxnSeq txnSeq = erpTxnSeqService.one(formMap);
			if(txnSeq == null){
				throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
						"此请求支付订单号不存在");
			}
			//3：判断提交的参数是否发生篡改
			String tempOrderAmount = txnSeq.getTxnAmt().trim();
			if(!tempOrderAmount.equals(orderAmount)){
				throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
						"订单支付金额和返回金额不一致");
			}
			String mount = "";
			List<Map> list = orpOrdersService.listBySql("select sum(a.total_amount)*100 as mount from erp_orders a  where a.order_id='"+orderId+"'");
			mount = list.get(0).get("MOUNT").toString();
			if(!mount.equals(tempOrderAmount)){
				throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
						"订单在提交支付时被篡改");
			}
			String qid = resArr[9];
			String respCode = resArr[10];
			String respMsg = resArr[11];
			String orderDate = txnSeq.getInTxnDt();
			String respTime = resArr[12];
			jsonObject = chinaUnionPayService.backNotify(orderId,qid,respCode,respMsg,orderDate,respTime,orderAmount);
			if(jsonObject.get("code").toString().equals("1")){
				orderService.payConfirmOrder(userId, orderId, Constants.ONLINE_PAYMENT.UNION_PAY, qid,Constants.PAY_CHANNEL.PAY_WEB);
				return jsonObject;
			}
			else{
				return executeRerutnFail(jsonObject);
			}
			
		}
		//交易类型为退货
		else if("04".equals(transType)){
			//TODO 
			return jsonObject;
		}else if("31".equals(transType)){
			//TODO 
			return jsonObject;
		}else{
			return jsonObject;
		}
		
	}
	/**
	 * 前台通知支付结果处理
	 * @param resArr
	 * @param signature
	 * @param signMethod 
	 * @param orderId     订单号
	 * @param userId      用户编码
	 * @param transType   交易类型
	 * @return
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	@Transactional
	public JSONObject frontNotify(String[] resArr, String signature, String signMethod,String orderId,String userId,String transType) {
		JSONObject jsonObject = new JSONObject();
		if (StringUtils.isBlank(userId)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"用户编码不能为空");
		}
		if (StringUtils.isBlank(orderId)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"订单号不能为空");
		}
		if (StringUtils.isBlank(signature)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"签名信息不能为空");
		}
		if (StringUtils.isBlank(signMethod)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"签名方法不能为空");
		}
		if (StringUtils.isBlank(transType)) {
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"交易类型不能为空");
		}
		Boolean signatureCheck = new QuickPayUtils().checkSign(resArr, signMethod, signature,ConfigService.getConfig(ChinaUnionPayConfig.KEY_UNIONPAY_SENDCERTKEY_PWD));
		System.out.println("==================验证签名："+signatureCheck);
		if(!signatureCheck){
			throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
					"支付返回签名有误");
		}
		//交易类型是消费
		System.out.println("==================交易类型："+transType);
		if("01".equals(transType)){
			//2:判断ErpTxnSeq中是否存在返回的请求支付订单号并且交易状态0的记录
			Map formMap = new HashMap();
			formMap.put(ErpTxnSeq.COL_ORDER_ID, orderId);
			formMap.put(ErpTxnSeq.COL_TXN_STATE, Constants.TXN_STATE.TXN_O0);
			formMap.put(ErpTxnSeq.COL_DEL_FLAG, "0");
			SqlUtis.prepareSql(formMap,
					SqlUtis.getSQL(formMap, "a."
							+ ErpTxnSeq.COL_ORDER_ID,Types.VARCHAR,SqlUtis.EQ),
							SqlUtis.getSQL(formMap, "a."
									+ ErpTxnSeq.COL_TXN_STATE,Types.VARCHAR,SqlUtis.EQ),
									SqlUtis.getSQL(formMap, "a."
											+ ErpTxnSeq.COL_DEL_FLAG,Types.VARCHAR,SqlUtis.EQ));
			ErpTxnSeq txnSeq = erpTxnSeqService.one(formMap);
			if(txnSeq == null){
				throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
						"此请求支付订单号不存在");
			}
			//3:判断请求回来之前orderseq对应的记录中的处理时间是否为空
			if(txnSeq.getResCode()!= null){
				throw new BusinessException(Constants.ERRORS.VALIDATE_ERROR_CODE,
						"此请求支付订单号已处理");
			}
			String qid = resArr[9];
			String respCode = resArr[10];
			String respMsg = resArr[11];
			String orderDate = txnSeq.getInTxnDt();
			String respTime = resArr[12];
			String orderAmount = resArr[6];
			jsonObject = chinaUnionPayService.frontNotify(orderId,qid,respCode,respMsg,orderDate,respTime,orderAmount);
			System.out.println(jsonObject.toString());
			if(jsonObject.get("code").toString().equals("1")){
				orderService.payRequestConfirmOrder(userId, orderId);
				return jsonObject;
			}
			else{
				return executeRerutnFail(jsonObject);
			}
		}
			//交易类型为退货
			else if("04".equals(transType)){
				//TODO 
				return jsonObject;
			}else if("31".equals(transType)){
				//TODO 
				return jsonObject;
			}else{
				return jsonObject;
			}
	}
	
}
